package com.hina.rec.application.service.system.impl;

import com.hina.rec.application.convert.system.MenuConvert;
import com.hina.rec.application.manager.system.MenuManager;
import com.hina.rec.application.service.system.MenuService;
import com.hina.rec.common.model.IdReq;
import com.hina.rec.common.utils.AssertUtil;
import com.hina.rec.domain.model.MenuDO;
import com.hina.rec.endpoint.req.system.MenuSaveReq;
import com.hina.rec.endpoint.req.system.MenuUpdateReq;
import com.hina.rec.endpoint.res.system.MenuRes;
import com.hina.rec.endpoint.res.system.MenuTreeRes;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 菜单管理Service实现类
 *
 * @author liaosp
 * @date 2024-01-10
 */
@Service
@RequiredArgsConstructor
public class MenuServiceImpl implements MenuService {

    private final MenuManager menuManager;

    @Override
    public boolean save(MenuSaveReq req) {
        MenuDO menuDO = MenuConvert.INSTANCE.toMenuDO(req);
        return menuManager.save(menuDO);
    }

    @Override
    public boolean update(MenuUpdateReq req) {
        // 检查数据是否存在
        MenuDO menu = menuManager.getById(req.getId());
        AssertUtil.notNull(menu, "菜单不存在");
        // 转换为实体对象并更新
        MenuDO menuDO = MenuConvert.INSTANCE.toMenuDO(req);
        return menuManager.updateById(menuDO);
    }

    @Override
    public boolean delete(Integer id) {
        // 检查数据是否存在
        MenuDO menu = menuManager.getById(id);
        AssertUtil.notNull(menu, "菜单不存在");
        return menuManager.removeById(id);
    }

    @Override
    public List<MenuRes> list() {
        List<MenuDO> menuList = menuManager.lambdaQuery()
                .orderByAsc(MenuDO::getSort)
                .list();
        return MenuConvert.INSTANCE.toMenuResList(menuList);
    }

    @Override
    public MenuRes detail(IdReq req) {
        MenuDO menu = menuManager.getById(req.getId());
        AssertUtil.notNull(menu, "菜单不存在");
        return MenuConvert.INSTANCE.toMenuRes(menu);
    }

    @Override
    public List<MenuTreeRes> tree() {
        // 获取所有菜单列表
        List<MenuDO> menuList = menuManager.lambdaQuery()
                // 状态为启用
                .eq(MenuDO::getStatus, true)
                .orderByAsc(MenuDO::getSort)
                .list();

        // 转换为MenuRes对象
        List<MenuTreeRes> menuResList = MenuConvert.INSTANCE.toMenuTreeResList(menuList);

        // 构建菜单树
        return buildMenuTree(menuResList);
    }

    /**
     * 构建菜单树
     *
     * @param menuList 菜单列表
     * @return 菜单树
     */
    private List<MenuTreeRes> buildMenuTree(List<MenuTreeRes> menuList) {
        // 按照父ID分组
        Map<Integer, List<MenuTreeRes>> parentIdMap = menuList.stream()
                .collect(Collectors.groupingBy(MenuTreeRes::getParentId));

        // 获取顶级菜单（parentId为0的菜单）
        List<MenuTreeRes> rootMenus = parentIdMap.getOrDefault(0, new ArrayList<>());

        // 递归设置子菜单
        rootMenus.forEach(menu -> setChildren(menu, parentIdMap));

        return rootMenus;
    }

    /**
     * 递归设置子菜单
     *
     * @param menu        当前菜单
     * @param parentIdMap 按父ID分组的菜单Map
     */
    private void setChildren(MenuTreeRes menu, Map<Integer, List<MenuTreeRes>> parentIdMap) {
        // 获取当前菜单的子菜单
        List<MenuTreeRes> children = parentIdMap.getOrDefault(menu.getId(), new ArrayList<>());

        // 设置子菜单
        if (!children.isEmpty()) {
            menu.setChildren(children);
            // 递归设置子菜单的子菜单
            children.forEach(child -> setChildren(child, parentIdMap));
        }
    }
}